local BattleCamera = class("BattleCamera")

local vector3Zero = Vector3.New(0,0,0)
local data = BattleConfigData

require "Battle/Battle"
require "Config/BattleConfigData"

function BattleCamera:ctor( ... )
	local arg = {...}
	local gameObject = arg[1]
	self.transform = gameObject:GetComponent(typeof(UnityEngine.Transform))
	self.camera = gameObject:GetComponent(typeof(UnityEngine.Camera))

	self.isDamping = false
	self.isScale = false

	self:calContraint()
end

function BattleCamera.Start(gameObject)
	local object = BattleCamera.new(gameObject)
	--Battle.camera = object
	Battle.setCamera(object)
	UpdateBeat:Add(object.update, object)
	return object
end

function BattleCamera.Destroy(gameObject, object)
	UpdateBeat:Remove(object.update, object)
	object.transform = nil
	object.camera = nil

	--Battle.camera = nil
	Battle.setCamera(nil)
end

function BattleCamera:calContraint()
	
	local resolution = UnityEngine.Screen.currentResolution
	--GameLog.Warning("resolution x = "..resolution.width.." y = "..resolution.height)
	self.resolution = {x = resolution.width, y = resolution.height}
	self.whRate = self.resolution.x / self.resolution.y
	self.currentSize = self.camera.orthographicSize
	self.sizeResolution = {x = 0, y = 0}
	self.sizeResolution.y = self.currentSize * data.pixelsPerUnit * 2
	self.sizeResolution.x = self.sizeResolution.y * self.whRate
	--GameLog.Warning("sizeResolution x = "..self.sizeResolution.x.." y = "..self.sizeResolution.y)

	self.scaleSizeResolution = {x = 0, y = 0}
	self.scaleSizeResolution.y = self.currentSize * data.scaleRate * data.pixelsPerUnit * 2
	self.scaleSizeResolution.x = self.scaleSizeResolution.y * self.whRate
	--GameLog.Warning("scaleSizeResolution x = "..self.scaleSizeResolution.x.." y = "..self.scaleSizeResolution.y)

	self.rect = {top =0, left=0, right=0, bottom=0}
	self.scaleRect = {top =0, left=0, right= 0, bottom = 0}

	if(data.bgResolution.x > self.sizeResolution.x) then
		local shift = (data.bgResolution.x - self.sizeResolution.x)/data.pixelsPerUnit/2
		self.rect.left = -shift
		self.rect.right = shift
	else
		self.rect.left = 0
		self.rect.right = 0
	end

	if(data.bgResolution.y > self.sizeResolution.y) then
		local shift = (data.bgResolution.y - self.sizeResolution.y)/data.pixelsPerUnit/2
		self.rect.top = shift
		self.rect.bottom = -shift
	else
		self.rect.top = 0
		self.rect.bottom = 0
	end

	if(data.bgResolution.x > self.scaleSizeResolution.x) then
		local shift = (data.bgResolution.x - self.scaleSizeResolution.x)/data.pixelsPerUnit/2
		self.scaleRect.left = -shift
		self.scaleRect.right = shift
	else
		self.scaleRect.left = 0
		self.scaleRect.right = 0
	end
	
	if(data.bgResolution.y > self.scaleSizeResolution.y) then
		local shift = (data.bgResolution.y - self.scaleSizeResolution.y)/data.pixelsPerUnit/2
		self.scaleRect.top = shift
		self.scaleRect.bottom = -shift
	else
		self.scaleRect.top = 0
		self.scaleRect.bottom = 0
	end
	--GameLog.Warning("scaleRect top  = "..self.scaleRect.top.." bottom = "..self.scaleRect.bottom.." left = "..self.scaleRect.left.." right = "..self.scaleRect.right)
end

function BattleCamera:constrainPos(pos, isScale)
	
	if(isScale) then
		pos.x = Mathf.Clamp(pos.x, self.scaleRect.left, self.scaleRect.right)
		pos.y = Mathf.Clamp(pos.y, self.scaleRect.bottom, self.scaleRect.top)
	else
		pos.x = Mathf.Clamp(pos.x, self.rect.left, self.rect.right)
		pos.y = Mathf.Clamp(pos.y, self.rect.bottom, self.rect.top)
	end

	return pos
end

function BattleCamera:startDamping(targetPos, smoothTime)
	self.isDamping = true
	self.targetPos = targetPos
	self.targetPos.z = self.transform.position.z
	--GameLog.Warning("startDamping x = ".. self.targetPos.x.." y = "..self.targetPos.y)
	self.targetPos = self:constrainPos(self.targetPos, true)
	--GameLog.Warning("startDamping constrainPos x = ".. self.targetPos.x.." y = "..self.targetPos.y)
	self.smoothTime = smoothTime
	self.speed = 1.0

	self.startDampTime = 0.0
	self.lastPostion = self.transform.position
	self.targetVector = self.targetPos - self.lastPostion
end

--[[
function BattleCamera:startDamping(targetPos, smoothTime)
	self.isDamping = true
	self.targetPos = targetPos
	self.targetPos.z = self.transform.position.z
	self.smoothTime = smoothTime
	self.currentVelocity = Vector3.New(0,0,0)
end
]]

function BattleCamera:startScaleByTime(scaleTime)
	self:startScaleSize(self.currentSize*data.scaleRate, 0.3)
end

function BattleCamera:startRecoverScaleByTime(scaleTime)
	self:startScaleSize(self.currentSize, 0.3)
end

function BattleCamera:startScaleSize(targetScale, scaleTime)
	self.isScale = true
	self.targetScale = targetScale
	self.scaleTime = scaleTime
	self.startScale = self.camera.orthographicSize
	self.startTime = 0

	if(Mathf.Abs(self.targetScale - self.startScale) < 1e-6) then
		self.isScale = false
	end
end

function BattleCamera:update()
	if(self.isDamping) then
		self.startDampTime = self.startDampTime + Time.deltaTime
		if(self.startDampTime < self.smoothTime) then
			local t = self.startDampTime / self.smoothTime
			local position = self.lastPostion + self.targetVector * t
			self.transform.position = position
		else
			self.isDamping = false
			self.transform.position = self.targetPos
		end
	end

	if(self.isScale) then
		self.startTime = self.startTime + Time.deltaTime
		local t = self.startTime / self.scaleTime
		local currentScale = Mathf.Lerp(self.startScale, self.targetScale, t)
		self.camera.orthographicSize = currentScale
		if(self.startTime > self.scaleTime) then
			self.isScale = false
		end
	end
end

--[[
function BattleCamera:update()
	if(self.isDamping) then
		local position = self.transform.position
		position, self.currentVelocity = Vector3.SmoothDamp(position, self.targetPos, self.currentVelocity, self.smoothTime)
		self.transform.position = position
		if(self.currentVelocity == vector3Zero) then
			self.isDamping = false
		end
	end

	if(self.isScale) then
		self.startTime = self.startTime + Time.deltaTime
		local t = self.startTime / self.scaleTime
		local currentScale = Mathf.Lerp(self.startScale, self.targetScale, t)
		self.camera.orthographicSize = currentScale
		if(self.startTime > self.scaleTime) then
			self.isScale = false
		end
	end
end
]]


return BattleCamera